﻿using Serilog;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Xml;

namespace TeBigScreen.Common
{
    public class ConfigItem
    {
        public string BasePath { get; set; }

        protected Config Config => Config.Default;

        public void Save() => Config.SaveConfig();


        public bool GetBool(string key, bool default_value = false)
        {
            var text = Config.GetConfigText(key);

            return string.IsNullOrWhiteSpace(text) ? default_value : Convert.ToBoolean( Convert.ToInt32(text));
        }

        public void SetBool(string key, bool value)
        {
            Config.SetConfigText(key, value ? "1" : "0");
        }

        public int GetInt(string key, int default_value = 0)
        {
            var text = Config.GetConfigText(key);

            return string.IsNullOrWhiteSpace(text) ? default_value : Convert.ToInt32(text);
        }

        public void SetInt(string key, int value)
        {
            Config.SetConfigText(key, value.ToString());
        }

        public double GetDouble(string key, double default_value = 0)
        {
            var text = Config.GetConfigText(key);

            return string.IsNullOrWhiteSpace(text) ? default_value : Convert.ToDouble(text);
        }

        public void SetDouble(string key, double value)
        {
            Config.SetConfigText(key, value.ToString());
        }
    }

    public class ConfigLogin : ConfigItem
    {
        private string LeftKey => $"{BasePath}/left";
        private string RightKey => $"{BasePath}/right";
        private string MainKey => $"{BasePath}/main";

        public bool Left
        {
            get => GetBool(LeftKey);
            set => SetBool(LeftKey, value);
        }

        public bool Right
        {
            get => GetBool(RightKey); 
            set => SetBool(RightKey, value); 
        }

        public bool Main
        {
            get => GetBool(MainKey); 
            set => SetBool(MainKey, value);
        }
    }

    public class ConfigCommon : ConfigItem
    {
        public string Service => Config.GetConfigText($"{BasePath}/service");

    }

    public class ConfigMap : ConfigItem
    {
        private string ZoomKey => $"{BasePath}/zoom";
        private string LatitudeKey => $"{BasePath}/center/latitude";
        private string LongitudeKey => $"{BasePath}/center/longitude";

        public double Zoom
        {
            get => GetDouble(ZoomKey);
            set => SetDouble(ZoomKey, value);
        }

        public double Latitude
        {
            get => GetDouble(LatitudeKey); 
            set => SetDouble(LatitudeKey, value); 
        }

        public double Longitude
        {
            get => GetDouble(LongitudeKey); 
            set => SetDouble(LongitudeKey, value); 
        }
    }

    public class BaseConfig
    {
        protected XmlDocument _xml = new XmlDocument();
        
        protected void LoadConfig(string path)
        {
            using (XmlReader reader = XmlReader.Create(path))
                _xml.Load(reader);
        }

        protected void SaveConfig(string path)
        {
            _xml.Save(path);
        }

        public void SetConfigText(string xpath, string value)
        {
            var node = _xml.SelectSingleNode(xpath);
            if (node != null)
                node.InnerText = value;
        }

        public string GetConfigText(string xpath)
        {
            return _xml.SelectSingleNode(xpath)?.InnerText ?? "";
        }

    }

    public class Config : BaseConfig
    {
        public static Config Default { get; } = new Config();

        public Config()
        {
            LoadConfig();
        }

        string _xml_path = Path.Combine(AppContext.BaseDirectory, "config.xml");

        public void LoadConfig()
        {
            try
            {
                LoadConfig(_xml_path);
            }
            catch (Exception ex)
            {
                Log.Error($"加载配置文件失败: {ex.Message}");
            }
        }

        public void SaveConfig()
        {
            try
            {
                SaveConfig(_xml_path);
            }
            catch (Exception ex)
            {
                Log.Error($"保存配置文件失败: {ex.Message}");
            } 
        }

        public ConfigCommon Common { get; } = new ConfigCommon { BasePath = "//config/common" };

        public ConfigMap Map { get; } = new ConfigMap { BasePath = "//config/ui/map" };
        public ConfigMap Map2 { get; } = new ConfigMap { BasePath = "//config/ui/map2" };

        public ConfigLogin Login { get; } = new ConfigLogin { BasePath = "//config/ui/login" };
    }
}
